Skip to content

[release-24.0] VDiff: save a sample for every drained extra row so reconciliation can match them (#20855) - #20943

Merged
mattlord merged 1 commit into
release-24.0from
backport-20855-to-release-24.0
Aug 28, 2026
Merged

[release-24.0] VDiff: save a sample for every drained extra row so reconciliation can match them (#20855)#20943
mattlord merged 1 commit into
release-24.0from
backport-20855-to-release-24.0

Conversation

@vitess-bot

@vitess-bot vitess-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Description

This is a backport of #20855

…n match them (#20855)

Signed-off-by: Matthias Crauwels <matthias.crauwels@planetscale.com>
Signed-off-by: Matt Lord <mattalord@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Matt Lord <mattalord@gmail.com>
Copilot AI balanced review requested due to automatic review settings August 28, 2026 19:06
@vitess-bot vitess-bot Bot added the Type: Enhancement Logical improvement (somewhere between a bug and feature) label Aug 28, 2026
@vitess-bot
vitess-bot Bot requested a review from mattlord as a code owner August 28, 2026 19:06
@vitess-bot vitess-bot Bot added Backport This is a backport Component: VDiff labels Aug 28, 2026
@vitess-bot
vitess-bot Bot requested a review from mcrauwel August 28, 2026 19:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Backports the VDiff fix for reconciling drained extra rows without false-positive mismatches.

Changes:

  • Samples every drained row up to the configured cap.
  • Tracks lossless samples and safely reconciles them.
  • Adds drain, resume-error, truncation, and reconciliation tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
workflow_differ.go Updates reconciliation and sample trimming.
workflow_differ_test.go Expands reconciliation coverage.
table_differ.go Reworks row draining and progress tracking.
table_differ_test.go Tests draining and stream failures.
report.go Adds lossless-sample metadata.
report_test.go Updates report expectations.
primitive_executor.go Removes the obsolete drain helper.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +589 to +590
if advanceSource {
lastProcessedRow = sourceRow

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65656c109e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +690 to +692
dr.ExtraRowsSource += drainedRows
dr.ProcessedRows += drainedRows
dr.ExtraRowsSourceDiffs = append(dr.ExtraRowsSourceDiffs, drainedDiffs...)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Checkpoint successfully drained source rows

When the target is exhausted immediately after an extra-target comparison, sourceRow is still held and the new advanceSource guard leaves lastProcessedRow at the preceding row (or nil), while this block successfully drains that held row and merges its count and sample into dr. If reconciliation, mismatch persistence, or the completed-state update subsequently fails in diffTable, the deferred progress update stores the advanced report without the corresponding source lastpk; resuming then streams those source rows again and double-counts them. Update the checkpoint to the final successfully drained source row atomically with merging drainedRows.

AGENTS.md reference: AGENTS.md:L119-L124

Useful? React with 👍 / 👎.

// deliberately affirmative: samples that are lossy (only-pks, truncated
// values) -- or that were persisted by an older binary and reloaded on
// resume -- lack it and are excluded from reconciliation.
LosslessValues bool `json:"LosslessValues,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add a release-note callout for the VDiff behavior change

This changes user-visible VDiff reconciliation results and also adds LosslessValues to serialized row samples, but the commit contains no release/deployment-note update. Add the required callout so operators and report consumers are informed of the changed behavior and JSON output.

AGENTS.md reference: AGENTS.md:L232-L234

Useful? React with 👍 / 👎.

var drainedDiffs []*RowDiff
for targetRow != nil {
if dr.ExtraRowsTarget+drainedRows < maxExtraRowsToCompare {
diffRow, err := td.genRowDiff(td.tablePlan.targetQuery, targetRow, reportOpts)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize drained target samples to the source projection

When a workflow projection transforms or renames columns, such as select c0 as c1, buildTablePlan preserves c0 as c1 in sourceQuery but emits c1 in targetQuery, and genRowDiff uses those formatted expressions as the Row map keys. Generating drained target samples from targetQuery therefore makes them unequal to otherwise identical source samples during the new reflect.DeepEqual(...Row...) reconciliation, so the drained-row fix still reports false extras for renamed, aggregate, and time-zone-adjusted projections; use a common projection/key representation for both sides.

Useful? React with 👍 / 👎.

// sample's provenance (the side-specific debug query, the lossless
// marker which differs between samples persisted by older binaries
// and current ones), not the row itself.
if reflect.DeepEqual(dr.ExtraRowsSourceDiffs[i].Row, dr.ExtraRowsTargetDiffs[j].Row) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Compare typed values before reconciling drained rows

The Row map is a display representation rather than a lossless encoding: for example, genRowDiff calls sqltypes.Value.ToString(), which represents both SQL NULL and an empty non-binary string as "", while LosslessValues only tracks omitted or truncated columns. With the newly collected samples for every drained row, a later drained row containing NULL can therefore compare equal here to the corresponding source row containing ''; reconciliation subtracts both extras and increments MatchingRows, hiding a real data difference that the old single drained sample would have left reported. Preserve and compare typed values or use an injective canonical encoding instead of the report map.

Useful? React with 👍 / 👎.

@mattlord
mattlord enabled auto-merge (squash) August 28, 2026 19:37
@mattlord
mattlord merged commit df1e99f into release-24.0 Aug 28, 2026
121 checks passed
@mattlord
mattlord deleted the backport-20855-to-release-24.0 branch August 28, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backport This is a backport Component: VDiff Type: Enhancement Logical improvement (somewhere between a bug and feature)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants